package com.allwees.bs.task.order.auto;

import com.allwees.bs.core.model.order.wf.order.EOrderAction;
import com.allwees.bs.core.model.order.wf.order.EOrderItemAction;
import com.allwees.bs.module.oms.dao.OrderDao;
import com.allwees.bs.module.oms.dao.OrderFlowDao;
import com.allwees.bs.module.oms.dao.OrderItemDao;
import com.allwees.bs.module.oms.entity.Order;
import com.allwees.bs.module.oms.entity.OrderItem;
import com.allwees.bs.module.oms.util.OrderUtil;
import com.allwees.bs.module.pms.dao.SkuDao;
import com.allwees.core.common.util.DateUtil;
import com.allwees.core.common.util.MapUtil;
import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.validation.constraints.NotNull;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;


@Slf4j
@Service

public class OrderUnPaidAutoCancelTask {
    @Autowired
    private OrderDao orderDao;

    @Autowired
    private OrderItemDao orderItemDao;

    /**
     * @Autowired private ProductDao productDao;
     **/

    @Autowired
    private SkuDao skuDao;

    @Autowired
    private OrderFlowDao orderFlowDao;

    @XxlJob(value = "orderUnPaidAutoCancelTask")
    public ReturnT<String> run(String s) {
        doTask();
        return ReturnT.SUCCESS;
    }

    private void doTask() {

        List<Order> unPaidOrders = this.orderDao.findUnPaidOrderList(new Date());
        if (CollectionUtils.isEmpty(unPaidOrders)) {
            return;
        }

        saveCancelOrder(unPaidOrders);

        Set<@NotNull String> orderUuids = unPaidOrders.stream().map(Order::getUuid).collect(Collectors.toSet());

        restituteQuantity(orderUuids);
    }

//    private void toCancelOrders(Order order) {
//
//        order.signal(EOrderAction.SYSTEM_CANCEL_BY_UNPAID);
//        order.setClosedAt(DateUtil. now());
//
//        OrderFlowEntity orderFlow = new OrderFlowEntity();
//        orderFlow.setOrderUuid(order.getUuid());
//        orderFlow.setAction(order.getLatestAction());
//        orderFlow.setBackState(order.getBackState());
//        orderFlow.setState(order.getState());
//
//        order.getFlows().add(orderFlow);
//    }

    private void saveCancelOrder(List<Order> unPaidOrders) {

        for (Order order : unPaidOrders) {
            order.signal(EOrderAction.SYSTEM_CANCEL_BY_UNPAID);
            Order updateOrder = new Order();
            updateOrder.setBackState(order.getBackState());
            updateOrder.setLatestAction(order.getLatestAction());
            updateOrder.setState(order.getState());
            updateOrder.setStatus(order.getStatus());
            updateOrder.setClosedAt(DateUtil.now());
            orderDao.updateByUuid(updateOrder, order.getUuid());

            orderFlowDao.insert(OrderUtil.flowOrder(order));
        }
    }

    private void restituteQuantity(Set<@NotNull String> orderUuids) {
        if (CollectionUtils.isEmpty(orderUuids)) {
            return;
        }

        List<OrderItem> orderItems = orderItemDao.selectByOrderUuids(orderUuids);

        Map<String, Integer> productQuantityMap = new HashMap<>(), skuQuantityMap = new HashMap<>();
        orderItems.forEach(o -> {
            MapUtil.put(productQuantityMap, o.getProductUuid(), o.getQuantity());
            MapUtil.put(skuQuantityMap, o.getSkuUuid(), o.getQuantity());
            o.signal(EOrderItemAction.SYSTEM_CANCEL_BY_UNPAID);
            OrderItem updateOrderItem = new OrderItem();
            updateOrderItem.setBackState(o.getBackState());
            updateOrderItem.setLatestAction(o.getLatestAction());
            updateOrderItem.setState(o.getState());
            //updateOrderItem.setClosedAt(DateUtil.now());
            orderItemDao.updateByUuid(updateOrderItem, o.getUuid());
        });

        //restituteSkuQuantity(skuQuantityMap);
    }

    private void restituteSkuQuantity(Map<String, Integer> skuQuantityMap) {
        if (CollectionUtils.isEmpty(skuQuantityMap)) {
            return;
        }
        skuQuantityMap.forEach((skuUuid, quantity) -> skuDao.updateAppendQuantity(skuUuid, quantity));
    }
}
